home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s2.arc / KBDINTP.MOD < prev    next >
Text File  |  1987-05-16  |  17KB  |  260 lines

  1. (*----------------------------------------------------------------------*)
  2. (*  Keyboard_Interrupt_Handler --- Replaces int 9 keyboard handler      *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Keyboard_Interrupt_Handler;
  6.  
  7. (*----------------------------------------------------------------------*)
  8. (*                                                                      *)
  9. (*     Procedure:  Keyboard_Interrupt_Handler                           *)
  10. (*                                                                      *)
  11. (*     Purpose:    Replaces standard interrupt 9 keyboard driver        *)
  12. (*                                                                      *)
  13. (*     Calling Sequence:                                                *)
  14. (*                                                                      *)
  15. (*                 -- Called by system only!                            *)
  16. (*     Remarks:                                                         *)
  17. (*                                                                      *)
  18. (*        This routine replaces the standard interrupt 9 keyboard       *)
  19. (*        driver so that the Alt-keypad combinations will work          *)
  20. (*        properly.                                                     *)
  21. (*                                                                      *)
  22. (*        This handler is a slight modification of one by               *)
  23. (*        Neil J. Rubenking.                                            *)
  24. (*                                                                      *)
  25. (*----------------------------------------------------------------------*)
  26.  
  27. (* STRUCTURED *) CONST
  28.    Ctrl_Keys : ARRAY[0..12] OF BYTE =
  29.                ( 119, 160, 132, 161, 115, 162, 116,
  30.                  163, 117, 164, 118, 165, 166 );
  31.  
  32. BEGIN (* Keyboard_Interrupt_Handler *)
  33.  
  34. INLINE(
  35.   $9C                          {           PUSHF                        ;Save the flags}
  36.   /$1E                         {           PUSH  DS                     ;Save registers used here}
  37.   /$50                         {           PUSH  AX}
  38.   /$53                         {           PUSH  BX}
  39.   /$51                         {           PUSH  CX}
  40.                                {;}
  41.   /$E4/$60                     {           IN    AL,$60                 ;Read the keyboard port}
  42.   /$88/$C1                     {           MOV   CL,AL                  ;Save the key in CL}
  43.                                {;}
  44.   /$3C/$80                     {           CMP   AL,$80                 ;Is is a RELEASE? If so,}
  45.   /$72/$03                     {           JB    ChkPrt                 ;}
  46.   /$E9/$7D/$00                 {           JMP   NormalKey              ;treat as Normal}
  47.                                {;}
  48.   /$3C/$37                     {ChkPrt:    CMP   AL,55                  ;Check for PrtSc key}
  49.   /$75/$03                     {           JNE   ChkEnt                 ;No -- may be Enter or keypad}
  50.   /$E9/$A7/$00                 {           JMP   ChkPrtSc               ;Yes -- process PrtSc key}
  51.                                {;}
  52.   /$3C/$1C                     {ChkEnt:    CMP   AL,28                  ;Check for ENTER key}
  53.   /$75/$03                     {           JNE   ChkBS                  ;No -- may be backspace}
  54.   /$E9/$8B/$00                 {           JMP   ChkEnter               ;Yes -- process enter key}
  55.                                {;}
  56.   /$3C/$0E                     {ChkBS:     CMP   AL,14                  ;Check for backspace key}
  57.   /$75/$03                     {           JNE   ChkKeyPad              ;No -- may be keypad}
  58.   /$E9/$B9/$00                 {           JMP   ChkBackSp              ;Yes -- process backspace key}
  59.                                {;}
  60.   /$3C/$47                     {ChkKeyPad: CMP   AL,71                  ;71 = value for HOME key}
  61.   /$72/$64                     {           JB    NormalKey              ;Below Home is normal}
  62.   /$3C/$53                     {           CMP   AL,83                  ;83 = value for DEL key}
  63.   /$7F/$60                     {           JG    NormalKey              ;Above Del is normal}
  64.                                {;}
  65.   /$B8/>KBD_ROM_DATA           {           MOV   AX,>Kbd_ROM_Data}
  66.   /$8E/$D8                     {           MOV   DS,AX                  ;Point DS at the ROM DATA}
  67.   /$A0/>KBD_FLAG               {           MOV   AL,[>Kbd_Flag]         ;Pick up shift key flags}
  68.                                {;}
  69.   /$A8/$F3                     {           TEST  AL,$F3                 ;Check if shifts other than alt, ctrl}
  70.   /$75/$54                     {           JNZ   NormalKey              ;If so, normal}
  71.                                {;}
  72.   /$88/$C3                     {           MOV   BL,AL                  ;Copy shift state}
  73.   /$80/$E3/$0C                 {           AND   BL,$0C                 ;Remove all but Ctrl + Alt}
  74.   /$80/$FB/$0C                 {           CMP   BL,$0C                 ;We only want one shift --}
  75.   /$74/$4A                     {           JE    NormalKey              ;If Ctrl + Alt, pass key on.}
  76.                                {;}
  77.                                {;   If we got here w/o a jump, it's one of our}
  78.                                {;   special keystrokes.}
  79.                                {;}
  80.   /$E8/$54/$00                 {Special:   CALL  ReadPort               ;Read the keyboard port.}
  81.                                {;}
  82.                                {;   Figure out TURBO code for key based upon scan code.}
  83.                                {;   For normal keys, add nothing.  For ALT keys, add 103.}
  84.                                {;   For control keys, special mapping is required.}
  85.                                {;}
  86.   /$A8/$08                     {           TEST  AL,8                   ;Check for ALT}
  87.   /$74/$06                     {           JZ    TestCtrl}
  88.                                {;}
  89.   /$80/$C1/$67                 {           ADD   CL,103                 ;+103 converts to TURBO code for ALT}
  90.   /$E9/$12/$00                 {           JMP   InsCode}
  91.                                {;}
  92.   /$A8/$04                     {TestCtrl:  TEST  AL,4                   ;Check for CTRL}
  93.   /$74/$0E                     {           JZ    InsCode                ;otherwise it is unshifted}
  94.                                {;}
  95.   /$8D/$1E/>CTRL_KEYS          {           LEA   BX,[>Ctrl_Keys]        ;Get address of ctrl key table}
  96.   /$80/$E9/$47                 {           SUB   CL,71                  ;Zero origin for key}
  97.   /$30/$ED                     {           XOR   CH,CH}
  98.   /$01/$CB                     {           ADD   BX,CX                  ;Get offset of new key value}
  99.   /$2E/$8A/$0F                 {       CS: MOV   CL,[BX]                ;Pick up TURBO value from table}
  100.                                {;}
  101.   /$80/$F4/$00                 {InsCode:   XOR   AH,0                   ;}
  102.   /$88/$C8                     {           MOV   AL,CL                  ;Get the key back from CL}
  103.   /$86/$C4                     {           XCHG  AH,AL}
  104.   /$8B/$1E/>KBD_TAIL           {           MOV   BX,[>Kbd_Tail]         ;Get tail of keyboard buffer}
  105.   /$89/$07                     {           MOV   [BX],AX                ;Put the key in the buffer}
  106.                                {;}
  107.   /$81/$C3/$02/$00             {           ADD   BX,2                   ;Advance the tail pointer}
  108.   /$81/$FB/>KBD_BUFFER_END     {           CMP   BX,>Kbd_Buffer_End     ;If at end of buffer...}
  109.   /$7C/$03                     {           JL    BufOK}
  110.                                {;}
  111.   /$BB/>KBD_BUFFER             {           MOV   BX,>Kbd_Buffer         ;...set back to beginning.}
  112.   /$89/$1E/>KBD_TAIL           {BufOK:     MOV   [>Kbd_Tail],BX}
  113.                                {;}
  114.   /$B0/$20                     {           MOV   AL,$20                 ;Send the EOI to the}
  115.   /$E6/$20                     {           OUT   $20,AL                 ;...interrupt controller}
  116.                                {;}
  117.   /$59                         {           POP   CX                     ;Restore registers}
  118.   /$5B                         {           POP   BX}
  119.   /$58                         {           POP   AX}
  120.   /$1F                         {           POP   DS}
  121.   /$9D                         {           POPF}
  122.   /$89/$EC                     {           MOV   SP,BP                  ;Undo what TURBO did at the}
  123.   /$5D                         {           POP   BP                     ;...start of this routine}
  124.                                {;}
  125.   /$CF                         {           IRET                         ;Let's blow this joint!}
  126.                                {;}
  127.                                {;          NormalKey}
  128.                                {;                                       ;Restore registers}
  129.   /$59                         {NormalKey: POP   CX}
  130.   /$5B                         {           POP   BX}
  131.   /$58                         {           POP   AX}
  132.   /$1F                         {           POP   DS}
  133.   /$9D                         {           POPF}
  134.   /$89/$EC                     {           MOV   SP,BP                  ;Jump to regular keyboard interrupt}
  135.   /$5D                         {           POP   BP                     ;... with a FAR JUMP}
  136.   /$2E/$FF/$2E/>KBD_SAVE_IADDR2{      CS:  JMP   FAR [>Kbd_Save_Iaddr2]}
  137.                                {;}
  138.                                {;          Read keyboard control port.}
  139.                                {;}
  140.   /$50                         {ReadPort:  PUSH  AX}
  141.   /$E4/$61                     {           IN    AL,$61                 ;Read keyboard control port}
  142.   /$88/$C4                     {           MOV   AH,AL}
  143.   /$0C/$80                     {           OR    AL,$80                 ;Set the "reset" bit and}
  144.   /$E6/$61                     {           OUT   $61,AL                 ;   send it back to control}
  145.   /$86/$C4                     {           XCHG  AH,AL                  ;Get back the control value}
  146.   /$E6/$61                     {           OUT   $61,AL                 ;Send it out also}
  147.   /$58                         {           POP   AX}
  148.   /$C3                         {           RET}
  149.                                {;}
  150.                                {;          Handle Enter key.  We're only interested in Alt-Enter,}
  151.                                {;          which we want to return as Esc + CHR( 28 ).}
  152.                                {;}
  153.   /$B8/>KBD_ROM_DATA           {ChkEnter:  MOV   AX,>Kbd_ROM_Data}
  154.   /$8E/$D8                     {           MOV   DS,AX                  ;Point DS at the ROM DATA}
  155.   /$A0/>KBD_FLAG               {           MOV   AL,[>Kbd_Flag]         ;Pick up shift key flags}
  156.                                {;}
  157.   /$A8/$F7                     {           TEST  AL,$F7                 ;Test for shifts other than ALT}
  158.   /$75/$D8                     {           JNZ   NormalKey              ;If so, treat as normal key.}
  159.                                {;}
  160.   /$A8/$08                     {           TEST  AL,8                   ;Check for ALT}
  161.   /$74/$D4                     {           JZ    NormalKey              ;Process as normal key if not ALT}
  162.                                {;}
  163.   /$80/$E9/$67                 {           SUB   CL,103                 ;Bias for ALT key code above}
  164.   /$EB/$85                     {           JMP   Special                ;Go insert ESC 28.}
  165.                                {;}
  166.                                {;          Handle PrtSc key.  We're only interested in Alt-PrtSc,}
  167.                                {;          which we want to return as Esc + CHR( 55 ).}
  168.                                {;}
  169.   /$B8/>KBD_ROM_DATA           {ChkPrtSc:  MOV   AX,>Kbd_ROM_Data}
  170.   /$8E/$D8                     {           MOV   DS,AX                  ;Point DS at the ROM DATA}
  171.   /$A0/>KBD_FLAG               {           MOV   AL,[>Kbd_Flag]         ;Pick up shift key flags}
  172.                                {;}
  173.   /$A8/$F3                     {           TEST  AL,$F3                 ;Test for shifts other than CTRL, ALT}
  174.   /$75/$C3                     {           JNZ   NormalKey              ;If so, treat as normal key.}
  175.                                {;}
  176.   /$A8/$08                     {           TEST  AL,8                   ;Check for ALT}
  177.   /$75/$0B                     {           JNZ   ChkPrtSc2              ;}
  178.                                {;}
  179.   /$A8/$04                     {           TEST  AL,4                   ;Check for CTRL}
  180.   /$74/$05                     {           JZ    ChkPrtSc1              ;}
  181.   /$B1/$72                     {           MOV   CL,114                 ;}
  182.   /$E9/$02/$00                 {           JMP   ChkPrtSc2              ;}
  183.                                {;}
  184.   /$B1/$FF                     {ChkPrtSc1: MOV   CL,255                 ;Not shifted.}
  185.                                {;}
  186.   /$E8/$BE/$FF                 {ChkPrtSc2: CALL  ReadPort               ;Read keyboard port.}
  187.   /$EB/$84                     {           JMP   InsCode                ;Go insert ESC + Code.}
  188.                                {;}
  189.                                {;          Handle backspace key.  We're only interested in Alt-backspace,}
  190.                                {;          which we want to return as Esc + CHR( 171 ).}
  191.                                {;}
  192.   /$B8/>KBD_ROM_DATA           {ChkBackSp: MOV   AX,>Kbd_ROM_Data}
  193.   /$8E/$D8                     {           MOV   DS,AX                  ;Point DS at the ROM DATA}
  194.   /$A0/>KBD_FLAG               {           MOV   AL,[>Kbd_Flag]         ;Pick up shift key flags}
  195.                                {;}
  196.   /$A8/$F7                     {           TEST  AL,$F7                 ;Test for shifts other than ALT}
  197.   /$75/$A3                     {           JNZ   NormalKey              ;If so, treat as normal key.}
  198.                                {;}
  199.   /$A8/$08                     {           TEST  AL,8                   ;Check for ALT}
  200.   /$74/$9F                     {           JZ    NormalKey              ;Process as normal key if not ALT}
  201.                                {;}
  202.   /$B1/$AB                     {           MOV   CL,171                 ;Alt-backspace code}
  203.   /$E8/$A7/$FF                 {           CALL  ReadPort               ;Read keyboard port}
  204.   /$E9/$6C/$FF                 {           JMP   InsCode                ;Go insert ESC 171.}
  205. );
  206.  
  207. END   (* Keyboard_Interrupt_Handler *);
  208.  
  209. (*----------------------------------------------------------------------*)
  210. (* Install_Keyboard_Handler --- Installs new interrupt 9 keyboard driver*)
  211. (*----------------------------------------------------------------------*)
  212.  
  213. PROCEDURE Install_Keyboard_Handler;
  214.  
  215. (*----------------------------------------------------------------------*)
  216. (*                                                                      *)
  217. (*     Procedure:  Install_Keyboard_Handler                             *)
  218. (*                                                                      *)
  219. (*     Purpose:    Replaces standard interrupt 9 keyboard driver        *)
  220. (*                                                                      *)
  221. (*     Calling Sequence:                                                *)
  222. (*                                                                      *)
  223. (*        Install_Keyboard_Handler;                                     *)
  224. (*                                                                      *)
  225. (*----------------------------------------------------------------------*)
  226.  
  227. BEGIN (* Install_Keyboard_Handler *)
  228.  
  229.                                    (* Set interrupt routine address *)
  230.  
  231.    DOS_Set_Intrpt( Kbd_Interrupt , CSeg , OFS( Keyboard_Interrupt_Handler ) );
  232.  
  233. END   (* Install_Keyboard_Handler *);
  234.  
  235. (*----------------------------------------------------------------------*)
  236. (*  Remove_Keyboard_Handler --- Removes installed interrupt 9 driver    *)
  237. (*----------------------------------------------------------------------*)
  238.  
  239. PROCEDURE Remove_Keyboard_Handler;
  240.  
  241. (*----------------------------------------------------------------------*)
  242. (*                                                                      *)
  243. (*     Procedure:  Remove_Keyboard_Handler                              *)
  244. (*                                                                      *)
  245. (*     Purpose:    Restores standard interrupt 9 keyboard driver        *)
  246. (*                                                                      *)
  247. (*     Calling Sequence:                                                *)
  248. (*                                                                      *)
  249. (*        Remove_Keyboard_Handler;                                      *)
  250. (*                                                                      *)
  251. (*----------------------------------------------------------------------*)
  252.  
  253. BEGIN (* Remove_Keyboard_Handler *)
  254.  
  255.                      (* Restore the previous interrupt pointers *)
  256.  
  257.    DOS_Set_Intrpt( Kbd_Interrupt , Kbd_Save_Iaddr1, Kbd_Save_Iaddr2 );
  258.  
  259. END   (* Remove_Keyboard_Handler *);
  260.